﻿using System;
using MathMethods;

namespace SLAUMethods
{
    class Program
    {
        static void Main(string[] args)
        {
            if (!System.IO.File.Exists("MathDLL.dll"))
            {
                Console.WriteLine("Нет файла библиотеки MathDLL.dll!");
                Console.WriteLine("Пожалуйста, скопируйте его в ту же папку, что и приложение.");
                Console.ReadKey();
                return;
            }

            // -------------------------------
            // -------------------------------
            // Методы Гаусса, Зейделя, Крамера
            //Matrix m = new Matrix(5, 4);
            //m[0, 0] = 3.82; m[0, 1] = 1.02; m[0, 2] = 0.75; m[0, 3] = -0.81; m[0, 4] = 4.87;
            //m[1, 0] = 1.05; m[1, 1] = 4.53; m[1, 2] = 0.98; m[1, 3] = -1.53; m[1, 4] = 6.93;
            //m[2, 0] = 0.73; m[2, 1] = -0.85; m[2, 2] = 4.71; m[2, 3] = 0.81; m[2, 4] = 16.4;
            //m[3, 0] = 0.88; m[3, 1] = -0.81; m[3, 2] = 1.28; m[3, 3] = 3.50; m[3, 4] = 17.1;
            //Matrix temp = m.Clone();

            //Console.WriteLine("Метод Гаусса");
            //NumericalMethods.Gauss(m).ShowRow();

            //m = temp.Clone();
            //Console.WriteLine("Метод Зайделя");
            //NumericalMethods.Seidel(m, 0.01).ShowRow();

            //m = temp.Clone();
            //Console.WriteLine("Метод Крамера");
            //NumericalMethods.CramersRule(m).ShowRow();

            // -------------------------------
            // -------------------------------
            // Прямой степенной метод
            //Matrix k = new Matrix(4, 4);
            //k[0, 0] = 2.66667; k[0, 1] = 0.82767; k[0, 2] = 0.02544; k[0, 3] = 0.33798;
            //k[1, 0] = 0.82767; k[1, 1] = 1.94798; k[1, 2] = -0.37811; k[1, 3] = 0.73481;
            //k[2, 0] = 0.02544; k[2, 1] = -0.37811; k[2, 2] = 2.24250; k[2, 3] = 0.78167;
            //k[3, 0] = 0.33798; k[3, 1] = 0.73481; k[3, 2] = 0.78167; k[3, 3] = 3.14290;

            //Matrix jeny = new Matrix(4, 4);
            //jeny[0, 0] = 1.93939; jeny[0, 1] = -0.89529; jeny[0, 2] = 0.32273; jeny[0, 3] = 0.45007;
            //jeny[1, 0] = -0.89529; jeny[1, 1] = 3.44670; jeny[1, 2] = 0.44146; jeny[1, 3] = 0.51739;
            //jeny[2, 0] = 0.32273; jeny[2, 1] = 0.44146; jeny[2, 2] = 2.75989; jeny[2, 3] = 0.28558;
            //jeny[3, 0] = 0.45007; jeny[3, 1] = 0.51739; jeny[3, 2] = 0.28558; jeny[3, 3] = 1.85403;

            //Matrix initialVector = new Matrix(1, 4);
            //initialVector[0, 0] = 1;
            //initialVector[1, 0] = 1;
            //initialVector[2, 0] = 1;
            //initialVector[3, 0] = 1;

            //Console.WriteLine("Прямой степенной метод");
            //double lambda = NumericalMethods.PowerMethod(k, initialVector, 0.000001);
            //Console.WriteLine("Спектральный радиус матрицы: " + lambda.ToString("F5"));
            //Console.WriteLine("Проверка найденного радиуса..");
            //Matrix a = new Matrix(4, 4);
            //for (int i = 0; i < 4; i++)
            //    for (int j = 0; j < 4; j++)
            //    {
            //        a[i, j] = k[i, j];
            //        if (i == j)
            //            a[i, j] = k[i, j] - lambda;
            //    }
            //double det = NumericalMethods.SquareMatrixDeterminant(a);
            //Console.WriteLine("Определитель матрицы |A - lambda * E| = " + det.ToString("F5"));
            //if (Math.Round(det) == 0)
            //    Console.WriteLine("Спектральный радиус найден правильно.");
            //else
            //    Console.WriteLine("Что-то пошло не так.\nПопробуйте увеличить точность.");

            // -------------------------------
            // -------------------------------
            // Интерполяционный метод Лагранжа
            Console.WriteLine("Интерполяционный метод Лагранжа");
            double[] xi = new double[] { -0.12, 1.68, 3.41, 5.62 };
            double[] yi = new double[] { 0.324, -0.6, -0.4, -0.21 };

            Console.WriteLine("Исходные точки");
            for (int i = 0; i < xi.Length; i++)
                Console.WriteLine("y(" + xi[i] + ") = " + yi[i]);

            Console.WriteLine("Проверка метода на исходных точках");
            for (int i = 0; i < xi.Length; i++)
            {
                double res = NumericalMethods.LagrangePolynomial(xi[i], xi, yi);
                if (res == yi[i])
                    Console.WriteLine("y(" + xi[i] + ") = " + res);
            }

            Console.WriteLine("Вычисление значений в промежуточных точках");
            for (int i = 1; i < xi.Length; i++)
            {
                double transitional = (xi[i - 1] + xi[i]) / 2;
                double res = NumericalMethods.LagrangePolynomial(transitional, xi, yi);
                Console.WriteLine("y(" + transitional + ") = " + res.ToString("F3"));
            }

            

            // arguments
            //double[] x_ = { 0.3, 0.5, 0.7, 0.9, 1.1 };
            //// values
            //double[] y_ = new double[x_.Length];
            //// fill values array
            //for (int i = 0; i < x_.Length; i++)
            //    y_[i] = NumericalMethods.FunctionForNewtonPolynomial(x_[i]);
            //// interpolation
            //double[] xi = { 0.2, 0.4, 0.6, 0.8, 1.0 };
            //double[] yi = new double[xi.Length];
            //for (int i = 0; i < xi.Length; i++)
            //    yi[i] = NumericalMethods.NewtonPolynomial(xi[i], x_, y_);
            //NumericalMethods.PrintFunctionValues(xi, yi, 3);

            //double[] yr = new double[xi.Length];
            //for (int i = 0; i < xi.Length; i++)
            //    yr[i] = NumericalMethods.FunctionForNewtonPolynomial(xi[i]);
            //NumericalMethods.PrintFunctionValues(xi, yr, 3);



            // Press any key to exit
            Console.ReadKey(true);
        }
    }
}
